# models.py
from django.db import models
from django.contrib.auth.models import User
from django.core.validators import MinValueValidator

class Transaction(models.Model):
    """收银交易记录"""
    PAYMENT_TYPES = [
        ('cash', '现金'),
        ('card', '银行卡'),
        ('wechat', '微信支付'),
        ('alipay', '支付宝'),
    ]
    amount = models.DecimalField(
        max_digits=12,
        decimal_places=2,
        validators=[MinValueValidator(0.01)]
    )
    payment_type = models.CharField(max_length=20, choices=PAYMENT_TYPES)
    timestamp = models.DateTimeField(auto_now_add=True)
    operator = models.ForeignKey(User, on_delete=models.PROTECT)
    tax_amount = models.DecimalField(max_digits=12, decimal_places=2)
    is_refund = models.BooleanField(default=False)

class FinancialReport(models.Model):
    """财务报表"""
    REPORT_PERIODS = [
        ('daily', '日报'),
        ('weekly', '周报'),
        ('monthly', '月报'),
        ('annual', '年报'),
    ]
    period_type = models.CharField(max_length=20, choices=REPORT_PERIODS)
    start_date = models.DateField()
    end_date = models.DateField()
    generated_at = models.DateTimeField(auto_now_add=True)
    report_data = models.JSONField()  # 存储结构化数据

class Budget(models.Model):
    """预算管理"""
    BUDGET_CATEGORIES = [
        ('marketing', '市场推广'),
        ('hr', '人力资源'),
        ('rd', '研发'),
        ('operations', '运营'),
    ]
    category = models.CharField(max_length=20, choices=BUDGET_CATEGORIES)
    amount = models.DecimalField(max_digits=12, decimal_places=2)
    start_date = models.DateField()
    end_date = models.DateField()
    actual_spending = models.DecimalField(max_digits=12, decimal_places=2, default=0)

class TaxRate(models.Model):
    """税率配置"""
    TAX_TYPES = [
        ('vat', '增值税'),
        ('income', '所得税'),
        ('business', '营业税'),
    ]
    tax_type = models.CharField(max_length=20, choices=TAX_TYPES, unique=True)
    rate = models.DecimalField(max_digits=5, decimal_places=2)  # 存储百分比值如16.00
    effective_date = models.DateField()

class CostCategory(models.Model):
    """成本分类"""
    name = models.CharField(max_length=100, unique=True)
    description = models.TextField(blank=True)

class CostRecord(models.Model):
    """成本记录"""
    category = models.ForeignKey(CostCategory, on_delete=models.PROTECT)
    amount = models.DecimalField(max_digits=12, decimal_places=2)
    occurred_at = models.DateField()
    description = models.TextField(blank=True)
# serializers.py
from rest_framework import serializers
from .models import *

class TransactionSerializer(serializers.ModelSerializer):
    class Meta:
        model = Transaction
        fields = '__all__'
        read_only_fields = ['operator', 'timestamp', 'tax_amount']
        extra_kwargs = {
            'amount': {'min_value': 0.01}
        }

    def validate(self, data):
        """自动计算税额"""
        tax_rate = TaxRate.objects.get(tax_type='vat').rate / 100
        data['tax_amount'] = data['amount'] * tax_rate
        return data

class FinancialReportSerializer(serializers.ModelSerializer):
    class Meta:
        model = FinancialReport
        fields = '__all__'

class BudgetSerializer(serializers.ModelSerializer):
    remaining = serializers.DecimalField(
        max_digits=12,
        decimal_places=2,
        read_only=True
    )

    class Meta:
        model = Budget
        fields = '__all__'
        validators = [
            serializers.UniqueTogetherValidator(
                queryset=Budget.objects.all(),
                fields=['category', 'start_date']
            )
        ]

class TaxRateSerializer(serializers.ModelSerializer):
    class Meta:
        model = TaxRate
        fields = '__all__'

class CostRecordSerializer(serializers.ModelSerializer):
    class Meta:
        model = CostRecord
        fields = '__all__'


# views.py
from rest_framework.views import APIView
from rest_framework.response import Response
from django.db.models import Sum, F
from .models import *
from .serializers import *


class TransactionView(APIView):
    """收银管理"""

    def post(self, request):
        serializer = TransactionSerializer(
            data=request.data,
            context={'operator': request.user}
        )
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=201)
        return Response(serializer.errors, status=400)

    def get(self, request):
        transactions = Transaction.objects.all()
        serializer = TransactionSerializer(transactions, many=True)
        return Response(serializer.data)


class FinancialReportView(APIView):
    """财务报表生成"""

    def get(self, request):
        period = request.query_params.get('period', 'daily')
        date_range = self.get_date_range(period)

        report_data = {
            'total_income': Transaction.objects.filter(
                timestamp__date__range=(date_range['start'], date_range['end']),
                is_refund=False
            ).aggregate(Sum('amount'))['amount__sum'] or 0,
            'total_refunds': Transaction.objects.filter(
                timestamp__date__range=(date_range['start'], date_range['end']),
                is_refund=True
            ).aggregate(Sum('amount'))['amount__sum'] or 0,
            'total_tax': TaxRecord.objects.filter(
                date__range=(date_range['start'], date_range['end'])
            ).aggregate(Sum('amount'))['amount__sum'] or 0,
            'costs': CostRecord.objects.filter(
                occurred_at__range=(date_range['start'], date_range['end'])
            ).aggregate(total=Sum('amount'))['total'] or 0
        }

        report = FinancialReport.objects.create(
            period_type=period,
            start_date=date_range['start'],
            end_date=date_range['end'],
            report_data=report_data
        )
        return Response(FinancialReportSerializer(report).data)

    def get_date_range(self, period):
        today = timezone.now().date()
        if period == 'daily':
            return {'start': today, 'end': today}
        elif period == 'weekly':
            return {'start': today - timedelta(days=today.weekday()), 'end': today}
        elif period == 'monthly':
            return {'start': today.replace(day=1), 'end': today}


class BudgetAlertView(APIView):
    """预算预警"""

    def get(self, request):
        budgets = Budget.objects.annotate(
            remaining=F('amount') - F('actual_spending')
        ).filter(remaining__lt=0)
        serializer = BudgetSerializer(budgets, many=True)
        return Response({'over_budget': serializer.data})


class TaxCalculationView(APIView):
    """税务管理"""

    def post(self, request):
        # 实际应接入税务系统API
        return Response({"message": "税务申报成功"}, status=200)
# urls.py
from django.urls import path
from .views import *

urlpatterns = [
    path('transactions/', TransactionView.as_view(), name='transactions'),
    path('financial-reports/', FinancialReportView.as_view(), name='financial-reports'),
    path('budgets/', BudgetAlertView.as_view(), name='budgets'),
    path('tax/', TaxCalculationView.as_view(), name='tax-calculation'),
    path('costs/', CostRecordView.as_view(), name='cost-records'),
]